#include "swpabstractlinkeddocument.h"

#include "../utils/documentmanager.h"

#include <icontainerdocument.h>
#include <idocumentdata.h>

using namespace core;
using namespace swp;

typedef QSharedPointer<IDocument> Document;

SwpAbstractLinkedDocument::SwpAbstractLinkedDocument(const QString& name,
    const MimeType& mimeType,
    const QSharedPointer<IContainerDocument>& container,
    bool isFuture) : ILinkedDocument(),
        m_valid(false),
        m_name(name),
        m_mimeType(mimeType),
        m_isDirty(false),
        m_isFuture(isFuture),
        m_container(container),
        m_data(0),
        m_links(),
        m_openedLinks()
{

}

SwpAbstractLinkedDocument::~SwpAbstractLinkedDocument()
{
    delete m_data;
}

void SwpAbstractLinkedDocument::setValid(bool valid)
{
    if (m_valid != valid)
    {
        m_valid = valid;
        makeDirty();
        emit validityChanged(valid);
    }
}

bool SwpAbstractLinkedDocument::isValid() const
{
    return m_valid;
}

bool SwpAbstractLinkedDocument::isFuture() const
{
    return m_isFuture;
}

bool SwpAbstractLinkedDocument::isLinked() const
{
    return true;
}

bool SwpAbstractLinkedDocument::isContainer() const
{
    return false;
}

bool SwpAbstractLinkedDocument::isDirty() const
{
    return m_isDirty;
}

QString SwpAbstractLinkedDocument::name() const
{
    return m_name;
}

core::MimeType SwpAbstractLinkedDocument::mimeType() const
{
    return m_mimeType;
}

QSharedPointer<core::IContainerDocument>
    SwpAbstractLinkedDocument::container() const
{
    return m_container;
}

void SwpAbstractLinkedDocument::setDirty(bool dirty)
{
    if (m_isDirty != dirty)
    {
        m_isDirty = dirty;

        emit dirtyChanged(m_isDirty);
    }
}

void SwpAbstractLinkedDocument::setFuture(bool future)
{
    if (m_isFuture != future)
    {
        m_isFuture = future;
    }
}

void SwpAbstractLinkedDocument::setContainer(
    const QSharedPointer<IContainerDocument>& container)
{
    if (m_container != container)
    {
        m_container = container;
        emit containerChanged();
    }
}

void SwpAbstractLinkedDocument::rename(const QString& name)
{
    if (m_name != name)
    {
        m_name = name;
        emit nameChanged();
    }
}

IDocumentData* SwpAbstractLinkedDocument::data() const
{
    return m_data;
}

void SwpAbstractLinkedDocument::makeDirty()
{
    setDirty();
}

QList<QSharedPointer<IDocument> > SwpAbstractLinkedDocument::links() const
{
    return m_links;
}

void SwpAbstractLinkedDocument::addLink(
    const QSharedPointer<IDocument>& document, bool projectIsOpening)
{
    if (!m_links.contains(document) &&
        linksTo().contains(document->mimeType()))
    {
        m_links.append(document);

        if (!projectIsOpening)
        {
            makeDirty();
        }

        openLinksToMemory();

        linksUpdated(projectIsOpening);

        closeOpenedLinks();
    }
}

void SwpAbstractLinkedDocument::removeLink(
    const QSharedPointer<IDocument>& document)
{
    if (m_links.contains(document))
    {
        m_links.removeAll(document);

        makeDirty();

        openLinksToMemory();

        linksUpdated(false);

        closeOpenedLinks();
    }
}

void SwpAbstractLinkedDocument::refreshLinkedModels()
{
    openLinksToMemory();

    linksUpdated(false);

    closeOpenedLinks();
}

void SwpAbstractLinkedDocument::linksUpdated(bool projectIsOpening)
{

}

void SwpAbstractLinkedDocument::openLinksToMemory()
{
    foreach (const Document& document, m_links)
    {
        if (document->isFuture())
        {
            DocumentManager::getInstance()->openDocumentToMemory(document);

            m_openedLinks.append(document);
        }
    }
}

void SwpAbstractLinkedDocument::closeOpenedLinks()
{
    foreach (const Document& document, m_openedLinks)
    {
        DocumentManager::getInstance()->closeDocument(document);
    }

    m_openedLinks.clear();
}
